package com.ts.conch.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ts.conch.common.result.CommonResult;
import com.ts.conch.dao.*;
import com.ts.conch.entity.*;
import com.ts.conch.service.ItsRoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class ItsRoleServiceImpl extends ServiceImpl<ItsRoleDao, TsRole> implements ItsRoleService {
    @Autowired
    private ItsRoleDao roleDao;
    @Autowired
    private ItsMenuDao menuDao;
    @Autowired
    private ItsPermissionDao permissionDao;
    @Autowired
    private ItsRoleMenuRelationDao roleMenuRelationDao;
    @Autowired
    private ItsAdminRoleRelationDao adminRoleRelationDao;
    @Autowired
    private ItsRolePermissionRelationDao rolePermissionRelationDao;
    @Autowired
    private ItsPermissionCategoryDao categoryDao;
    
    /** 日志打印工具 **/
    private static final Logger logger = LoggerFactory.getLogger(ItsRoleServiceImpl.class);

    @Override
    public CommonResult<?> create(TsRole role) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.create] - 开始运行 - 新增角色role:{}", JSON.toJSON(role));
        CommonResult<?> commonResult = CommonResult.failed("系统异常,新增角色失败!");
        role.setSort(0);
        int result = roleDao.insert(role);
        if (1 == result) {
            commonResult = CommonResult.success(role, "新增角色成功!");
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.create] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> update(TsRole role) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.update] - 开始运行 - 修改角色role:{}", JSON.toJSON(role));
        CommonResult<?> commonResult = CommonResult.failed("系统异常,更新角色失败!");
        int result = roleDao.updateById(role);
        if (1 == result) {
            commonResult = CommonResult.success(role, "修改成功!");
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.update] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<TsRole> updateRoleStatus(Map<String, Object> params) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.updateRoleStatus] - 开始运行 - 修改指定角色的状态params:{}", JSON.toJSON(params));
        CommonResult<TsRole> commonResult = CommonResult.failed("系统异常,更新角色失败!");
        TsRole role = new TsRole();
        String roleId = (String) params.get("roleId");
        int status = (int) params.get("status");
        role.setId(roleId);
        role.setStatus(status);
        int result = roleDao.updateById(role);
        if (1 == result) {
            commonResult = CommonResult.success(role, "更新成功!");
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.updateRoleStatus] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> delete(String roleId) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.delete] - 开始运行 - 删除角色roleId:{}", roleId);
        CommonResult<?> commonResult = CommonResult.failed("系统异常,删除角色失败!");
        int result = roleDao.deleteById(roleId);
        if (1 == result) {
            LambdaQueryWrapper<TsRoleMenuRelation> queryWrapper = new LambdaQueryWrapper<TsRoleMenuRelation>();
            queryWrapper.eq(TsRoleMenuRelation::getRoleId, roleId);
            result = roleMenuRelationDao.delete(queryWrapper);
            if (result >= 0) {
                LambdaQueryWrapper<TsAdminRoleRelation> queryWrapper1 = new LambdaQueryWrapper<TsAdminRoleRelation>();
                queryWrapper1.eq(TsAdminRoleRelation::getRoleId, roleId);
                result = adminRoleRelationDao.delete(queryWrapper1);
                if (result >= 0) {
                    LambdaQueryWrapper<TsRolePermissionRelation> queryWrapper2 = new LambdaQueryWrapper<TsRolePermissionRelation>();
                    queryWrapper2.eq(TsRolePermissionRelation::getRoleId, roleId);
                    result = rolePermissionRelationDao.delete(queryWrapper2);
                    if (result >= 0) {
                        commonResult = CommonResult.success("", "删除角色成功!");
                    }
                }
            }
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.delete] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> list(String enterpriseId) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.list] - 开始运行 - 获取所有角色列表enterpriseId:{}", enterpriseId);
        CommonResult<?> commonResult = CommonResult.failed("系统异常,获取角色列表失败!");
        LambdaQueryWrapper<TsRole> queryWrapper = new LambdaQueryWrapper<TsRole>();
        //查询出已启用的角色列表
        queryWrapper.eq(TsRole::getStatus, 1);
        queryWrapper.eq(TsRole::getEnterpriseId, enterpriseId);
        List<TsRole> roleList = roleDao.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(roleList)) {
            commonResult = CommonResult.success(roleList, "获取角色列表成功!");
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.list] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> list(Map<String, Object> params) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.list] - 开始运行 - 分页获取角色列表params:{}", JSON.toJSON(params));
        CommonResult<?> commonResult = CommonResult.failed("系统异常,分页查询角色列表失败!");
        LambdaQueryWrapper<TsRole> queryWrapper = new LambdaQueryWrapper<TsRole>();
        String page = (String) params.get("page");
        String size = (String) params.get("size");
        String name = (String) params.get("name");
        Long enterpriseId = (Long) params.get("enterpriseId");
        IPage<TsRole> pageParams = new Page<TsRole>();
        pageParams.setCurrent(Long.parseLong(page));
        pageParams.setSize(Long.parseLong(size));
        queryWrapper.like(TsRole::getName, name);
        IPage<TsRole> pageList = roleDao.selectPage(pageParams, queryWrapper);
        if (CollectionUtil.isNotEmpty(pageList.getRecords())) {
            pageList.getRecords().stream().forEach(role -> {
                List<String> menus = new ArrayList<String>();
                List<String> Permissions = new ArrayList<String>();
                List<TsMenu> menuList = roleDao.getMenuListByRoleId(role.getId());
                List<TsPermission> PermissionList = roleDao.getPermissionListByRoleId(role.getId());
                if (CollectionUtil.isNotEmpty(menuList)) {
                    menuList.stream().forEach(menu -> menus.add(menu.getTitle()));
                }
                if (CollectionUtil.isNotEmpty(PermissionList)) {
                    PermissionList.stream().forEach(Permission -> Permissions.add(Permission.getName()));
                }
                role.setMenuList(menus);
                role.setPermissionList(Permissions);
            });
            commonResult = CommonResult.success(pageList);
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.list] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> getMenuList(String adminId) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.getMenuList] - 开始运行 - 根据管理员ID获取对应菜单adminId:{}", adminId);
        CommonResult<?> commonResult = CommonResult.failed("系统异常,获取菜单列表失败!");
        List<Map<String, Object>> menuMapList = new ArrayList<Map<String, Object>>();
        try {
            List<TsMenu> menuLists = roleDao.getMenuList(adminId);
            if (CollectionUtil.isNotEmpty(menuLists)) {
                List<TsMenu> finalMenuLists = menuLists;
                List<TsMenu> resultList = menuLists.stream()
                        .filter(menu -> menu.getParentId().equals(0L)).sorted(Comparator.comparing(TsMenu::getSort))
                        .map(menu -> covertMenuNode(menu, finalMenuLists)).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(resultList)) {
                    resultList.stream().forEach(menu -> {
                        Map<String, Object> menuMap = menuToMap(menu);
                        menuMapList.add(menuMap);
                    });
                }
            }
            commonResult = CommonResult.success(menuMapList);
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.getMenuList] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<List<TsMenu>> listMenu(String roleId) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.listMenu] - 开始运行 - 获取角色相关菜单roleId:{}", roleId);
        CommonResult<List<TsMenu>> commonResult = CommonResult.failed("系统异常,获取菜单列表失败!");
        List<TsMenu> menuList = roleDao.getMenuListByRoleId(roleId);
        if (CollectionUtil.isNotEmpty(menuList)) {
            commonResult = CommonResult.success(menuList);
        } else {
            menuList = new ArrayList<TsMenu>();
            commonResult = CommonResult.success(menuList);
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.listMenu] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> listPermission(String roleId) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.listPermission] - 开始运行 - 获取角色相关资源roleId:{}", roleId);
        CommonResult<?> commonResult = CommonResult.failed("系统异常,获取资源列表失败!");
        LambdaQueryWrapper<TsPermissionCategory> queryWrapper = new LambdaQueryWrapper<TsPermissionCategory>();
        List<Map> idList = new ArrayList<Map>();
        List<TsPermissionCategory> categoryList = categoryDao.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(categoryList)) {
            categoryList.stream().forEach(category -> {
                category.setTitle(category.getName());
                List<TsPermission> PermissionList = roleDao.getPermissionListByRoleId(roleId);
                List<TsPermission> children = new ArrayList<TsPermission>();
                if (CollectionUtil.isNotEmpty(PermissionList)) {
                    PermissionList.stream().forEach(Permission -> {
                        if (category.getId().equals(Permission.getCategoryId())) {
                            children.add(Permission);
                        }
                    });
                    category.setChildren(children);
                }
            });
            List<TsPermissionCategory> resultList = categoryList.stream().filter(category -> CollectionUtil.isNotEmpty(category.getChildren())).collect(Collectors.toList());
            resultList.stream().forEach(category -> {
                Map<String, Object> idMap = new HashMap<String, Object>(16);
                idMap.put("id", category.getId().toString());
                idList.add(idMap);
                category.getChildren().stream().forEach(Permission -> {
                    Map<String, Object> PermissionMap = new HashMap<String, Object>(16);
                    PermissionMap.put("id", Permission.getId().toString());
                    idList.add(PermissionMap);
                });
            });
            commonResult = CommonResult.success(idList);
        } else {
            commonResult = CommonResult.success(idList);
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.listPermission] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> allocMenu(String roleId, List<String> menuIds) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.allocMenu] - 开始运行 - 给角色分配菜单roleId:{},menuIds:{}", roleId,menuIds);
        CommonResult<?> commonResult = CommonResult.failed("系统异常,分配菜单失败!");
        LambdaQueryWrapper<TsRoleMenuRelation> queryWrapper = new LambdaQueryWrapper<TsRoleMenuRelation>();
        queryWrapper.eq(TsRoleMenuRelation::getRoleId, roleId);
        int result = roleMenuRelationDao.delete(queryWrapper);
        if (result >= 0) {
            for (String menuId : menuIds) {
                TsRoleMenuRelation roleMenuRelation = new TsRoleMenuRelation();
                roleMenuRelation.setMenuId(menuId);
                roleMenuRelation.setRoleId(roleId);
                roleMenuRelationDao.insert(roleMenuRelation);
            }
            commonResult = CommonResult.success("", "分配成功!");
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.allocMenu] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<?> allocPermission(String roleId, List<String> permissionIds) {
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.allocPermission] - 开始运行 - 给角色分配资源roleId:{},menuIds:{}", roleId,permissionIds);
        CommonResult<?> commonResult = CommonResult.failed("系统异常,分配资源失败!");
        LambdaQueryWrapper<TsRolePermissionRelation> queryWrapper = new LambdaQueryWrapper<TsRolePermissionRelation>();
        queryWrapper.eq(TsRolePermissionRelation::getRoleId, roleId);
        int result = rolePermissionRelationDao.delete(queryWrapper);
        if (result >= 0) {
            for (String PermissionId : permissionIds) {
                TsRolePermissionRelation rolePermissionRelation = new TsRolePermissionRelation();
                rolePermissionRelation.setRoleId(roleId);
                rolePermissionRelation.setPermissionId(PermissionId);
                rolePermissionRelationDao.insert(rolePermissionRelation);
            }
            commonResult = CommonResult.success("", "分配成功!");
        }
        logger.info("[角色管理] - 程序[ItsRoleServiceImpl.allocPermission] - 结束运行 - 返回结果:{}", JSON.toJSON(commonResult));
        return commonResult;
    }

    @Override
    public CommonResult<List<Map<String, Object>>> queryAdminResourceBtn(String adminId) {
        return null;
    }

    /**
     * 将TsMenu设置children属性
     */
    private TsMenu covertMenuNode(TsMenu menu, List<TsMenu> menuList) {
        TsMenu node = new TsMenu();
        BeanUtils.copyProperties(menu, node);
        List<TsMenu> children = menuList.stream()
                .filter(subMenu -> subMenu.getParentId().equals(menu.getId())).sorted(Comparator.comparing(TsMenu::getSort))
                .map(subMenu -> covertMenuNode(subMenu, menuList)).collect(Collectors.toList());
        node.setChildren(children);
        return node;
    }

    private Map<String, Object> menuToMap(TsMenu menu) {
        List<Map<String, Object>> childList = new ArrayList<Map<String, Object>>();
        Map<String, Object> menuMap = new HashMap<>(16);
        List<String> accessList = new ArrayList<String>();
        Map<String, Object> metaMap = new HashMap<String, Object>(16);
        menuMap.put("path", menu.getPath());
        menuMap.put("component", menu.getComponent());
        if (menu.getHidden().equals(0)) {
            metaMap.put("hideInMenu", false);
        } else {
            metaMap.put("hideInMenu", true);
        }
        accessList.add(menu.getName());
        metaMap.put("access", accessList);
        metaMap.put("icon", menu.getIcon());
        if (menu.getNotCache().equals(0)) {
            metaMap.put("notCache", true);
        } else {
            metaMap.put("notCache", false);
        }
        metaMap.put("title", menu.getTitle());
        menuMap.put("meta", metaMap);
        menuMap.put("name", menu.getName());
        menuMap.put("parentId", menu.getParentId());
        menuMap.put("id", menu.getId().toString());
        if (CollectionUtil.isNotEmpty(menu.getChildren())) {
            menu.getChildren().stream().forEach(childMenu -> {
                Map<String, Object> childmenuMap = menuToMap(childMenu);
                childList.add(childmenuMap);
            });
            menuMap.put("children", childList);
        }
        return menuMap;
    }

}
